#include<stdlib.h>
#include "file.h"

/**  Procedure libererFile
 *   Libère la mémoire occupée par la File
 *   La mémoire occupée par la suite d'états est elle auusi libérée
 *   La mémoire correspondant aux états de la suite est libérée
 *   Cette dernière opération est effectuée par une procédure libérerEtat qui doit être fournie
 *   La signature de la procédure  doit être 
 *       void libererEtat(Etat *e);
 *
 *    Arguments 
 *         File *f : la file à libérer
 *
*/


void libererFile(File *f) {
  Queue *q=f->debut, *aux;
  while ( q != NULL ) {
    libererEtat((q->element)) ;
    aux = q;
    q = q->suivant;
    free(aux);
  }
  free(f);
} 


/**  Fonction  nouvelleFile
 *   Crée une nouvelle file vide
 * 
 *   Retourne:
 *              un pointeur sur la nouvelle file  
 */


File *nouvelleFile(void){
  File *f;

  f= (File *) malloc(sizeof(File));
  if (  f!= NULL) {
    f->LONGUEUR_MAX_FILE = 0;
    f->LONGUEUR_EFFECTIVE = 0;
    f->debut=NULL;
    f->fin=NULL;
  }
  return f;
 }




/**  Fonction  estVide
 *   Teste si la file est vide 
 *
 *   Paramètre:
 *              File *f: la file à tester 
 * 
 *   Retourne:
 *              O: si la file contient au moins un Etat
 *              1: si la file ne contient aucun Etat
 *
 *
 *   La signature forme de la fonction  est   
 *
 *            int estVide(File *f);
 * 
 *   L'implémentation effective est réalisé en utilisant une Macro.
 *   Ceci permet d'économiser un appel de fonction, tout en maintenant l'encapsulation.
 *
 */


//int estVide(File *f){
//  return 0;
//}



/**  Procedure  enfiler
 *   Ajoute un Etat à une File
 *
 *   Paramètres:
 *              File *f: la file dans laquelle on veut ajouter un Etat.
 *            
 *              Etat *e: L'Etat à ajouter. 
 * 
 *   
 */





void enfiler(File *f, Etat *e){
  Queue *q= (Queue * ) malloc((sizeof(Queue)));
  q->element = e;
  q->suivant = NULL;
  if (f->LONGUEUR_EFFECTIVE == 0)
    f->debut=f->fin = q;
  else {
    f->fin->suivant  = q;
    f->fin = q; 
  }
  f->LONGUEUR_EFFECTIVE += 1;
  if ( f->LONGUEUR_EFFECTIVE > f->LONGUEUR_MAX_FILE )
    f-> LONGUEUR_MAX_FILE = f->LONGUEUR_EFFECTIVE;
			      
}



/**  Procedure  enfilerUnique
 *   Teste si un Etat est  présent dans la File.
 *   Ajoute cet élément s'il n'est pas déjà présent 
 *
 *   Paramètres:
 *              File *f: la file dans laquelle on veut ajouter un Etat.
 *            
 *              Probleme *p : Le problème qui définit le contexte de l'état à ajouter
 *
 *              Etat *e: L'Etat à ajouter. 
 * 
 *   La comparaison des etats dans le contexte d'un probleme donné est effectuée à l'aide d'une fonction   estEgal de signature 
 *
 *              int estEgal(Probleme *p, Etat *e1, Etat *e2);
 *
 *    Cette fonction doit être fournie avaec la définition des problèmes et des états. 
 */



void enfilerUnique(File *f, Probleme *p, Etat *e) {
  Queue *q;
  if ( f->LONGUEUR_EFFECTIVE == 0 ) {
    enfiler(f, e);
    return;
  }
    
  q=f->debut; 
  while ((q != NULL) && ( !estEgal(p, e, q->element))) q= q->suivant;
  if (q == NULL ) enfiler(f, e);
}



/**  Fonction  defiler
 *   Retire un Etat dans une file  
 *
 *   Paramètre:
 *              File *f: la file dont il faut retirer un Etat
 * 
 *   Retourne:
 *              Etat * : l'état retiré
 *
 */

Etat *defiler(File *f){
  Etat *e =NULL;
  Queue *q ;
  if (f->LONGUEUR_EFFECTIVE == 0 )
    return NULL;
  else{
    q = f->debut;
    e = q->element;
    f->debut = q->suivant;
    f->LONGUEUR_EFFECTIVE -= 1;
    free(q);
  }
  
  return e;
}

  

/**  Fonction  longueurMax
 *   Fournit la longueur de de la plus longue suite d'Etats manipulée en utilisant la File 
 *
 *   Paramètre:
 *              File *f: la file à étudier
 * 
 *   Retourne:
 *              Un entier : La longueur recherchée
 *              1: si la file ne contient aucun Etat
 *
 *
 *   La signature forme de la fonction  est   
 *
 *            int longueurMax(File *f);
 * 
 *   L'implémentation effective est réalisé en utilisant une Macro.
 *   Ceci permet d'économiser un appel de fonction, tout en maintenant l'encapsulation.
 *
 */


//  int longueurMax(File *f){
//  return 0;
// }
